`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    20:55:43 03/10/2013 
// Design Name: 
// Module Name:    main 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
////////////////////////////////////////////////////////////////////

// Glossary / Notes
//
// ADP - arduino data port.
//   A 4-bit port through which you access the CPLD's internal ADP
//   latch, an 8-bit wide byte. The LSB line controls whether you
//   access the upper or lower 4 bits, and the arduino-centric
//   nADPRD/nADPWR pins control whether the latch is written to or
//   read from.

// BOOTSTRAP
//   When BL is asserted then we will open the byte latch onto the
//   bus and disable the RAM whenever rd & mreq is true.

// IO REQUESTS
//   When ioqr and !m1 and a7 is true then the z80 is requesting IO.
//   Set the z80's wait line. If rd then disable RAM and open the
//   byte latch on to the data bus, if wr then load the byte latch
//   from the bus.

// LATCH ACCESS
//   When adprd is asserted 4 bits of the latch content are placed
//   on the adp for the arduino to access, 7:4 if lsb is false else
//   3:0. When adpwr is asserted 4 bits of the latch are taken from
//   the the adp, 7:4 if lsb is false else 3:0.


// Here is the physical signal list, in no particular order.
// The signals are mapped to pins in the 'floorplan'.
// Signals prefixed with 'n' are active low.
// The names of signals are typically in mixed case in comments,
// but all lower case is used throughout the code.

module main(
	inout[3:0] adpbus,			// analog 0..3

	input lsb,						//    "   4

	output nwait,					//    "   5

	input ad0,						// digital 0/rx  **
	input ad1,						//    "    1/tx  **
	
	output nrdwr,					//    "    2

	input clkin,					//    "    3/pwm
	input nbl,						//    "    4
	input nwaitclr,				//    "    5/pwm
	input nadpwr,					//    "    6/pwm
	input nadprd,					//    "    7

	output obligatoryled,

	input a7,
	input nrd,
	input niorq,
	input nwr,
	input nmreq,
	input nm1,

	inout[7:0] databus,

	output nramce,
	output z80clk,

	input nreset,					// digital 12
	
	input x0,						// **
	input x1							// **
	);

// ** = unused


// Registers are the holding place for values.
//  They retain their value once written to.
//  You can assign values to registers within always@(..) blocks*,
//  but you can't give them values using 'assign'
// 
// * and always blocks can only output to wires or regs, never to
// ports.

reg[7:0] latch;			// arduino data port latch


// CLOCK

// assign will continuously drive the port specified on the LHS with
// the value of the expression on the RHS.
//
assign z80clk = clkin;

// Echo the z80's RD signal. This can be used with nwait - amongst
// other things.
//
assign nrdwr = nrd;

// Wires are used to transport a signal.
//  Here the signal is the result of the expression.
//  The wire is used as an input to an always block, or expression.
//  Wires must be driven continuously, unlike registers.

//  IOREQUEST is true when a real IORQ occurs at address 0x80-0xff.
//  If M1 is asserted at the same time as IORQ then it's an IRQ ACK.
//
wire iorequest;
assign iorequest = !niorq & nm1 & a7 & nreset;

// Indicates an IO write.
//
wire iowrite;
assign iowrite = iorequest & !nwr;


// When OPLATCH is true then the content of the latch will be
// output onto the data bus.
//
// OPLATCH will be true when:
//  RESET is not asserted
//  the z80 performs an IO read
//  a memory read occurs with the BL flag asserted.
//
wire oplatch;
assign oplatch = ((iorequest & !nrd) | (!nmreq & !nrd & !nbl)) & nreset;

// The databus module handles the nitty-gritty of the...databus.
//
databus vdb(oplatch, nmreq, latch, databus, nramce);


// If adpwr is asserted then copy data from the adp into the latch.
// Otherwise it's an IO write by the z80 so copy the content of the
// data bus into the latch.
//
// The arduino should never write to the adp when the z80 writes.
//
always@(negedge nadpwr or posedge iowrite)
	if (iowrite)
		latch = databus;
	else
		if(lsb)
			latch[3:0] = adpbus[3:0];
		else
			latch[7:4] = adpbus[3:0];

// if the arduino wants to read the adp then we output the appropriate
// bits, otherwise we make the adp port hi-z
//
assign adpbus[3:0] = !nadprd ? (lsb ? latch[3:0] : latch[7:4]) : 4'bz;



// When the z80 makes an IO request we immediately assert its wait line.
// This will remain asserted until the arduino writes to waitclr at which
// point the signal is deasserted and the processor continues running.

// "During T2 and every subsequent Tw, the CPU samples the WAIT line with 
// the falling edge of Clock. If the WAIT line is active at this time, another 
// WAIT state is entered during the following cycle."

wire waitffreset = nreset & nwaitclr;

ndff waitff(1'b0, iorequest, waitffreset, nwait);



// Uncomment this to have a blinky clock-driven LED.
// Widen the counter reg to decrease the flash frequency.
//
//reg[8:0] counter;
//always@(negedge clkin)
//  counter = counter + 1;
//assign obligatoryled = counter[8];

assign obligatoryled = clkin;

endmodule
